import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from datetime import datetime


def load_data():
    """加载数据并显示基本信息"""
    df = pd.read_excel("新浪财经历史分红数据.xlsx", engine='openpyxl')
    print(f"数据形状: {df.shape}")
    print("列名:", df.columns.tolist())
    print("\n前5行数据:")
    print(df.head())
    return df


def check_duplicates(df):
    """检查重复值"""
    print("\n重复值检查:")
    # 检查可能存在的列
    check_columns = []
    for col in ['代码', '名称', '详细']:
        if col in df.columns:
            check_columns.append(col)

    if check_columns:
        duplicates = df.duplicated(subset=check_columns).sum()
        print(f"基于列 {check_columns} 的重复行数: {duplicates}")
    else:
        print("未找到指定的列进行重复值检查")


def clean_data(df):
    """数据清洗"""
    print("\n数据清洗...")

    # 清理数值列 - 动态识别数值列
    numeric_patterns = ['股息', '分红', '融资', '次数', '总额']
    numeric_columns = []

    for col in df.columns:
        if any(pattern in col for pattern in numeric_patterns):
            numeric_columns.append(col)

    print(f"识别到的数值列: {numeric_columns}")

    for col in numeric_columns:
        if col in df.columns:
            # 移除百分号、单位等
            df[col] = df[col].astype(str).str.replace('%', '').str.replace('亿元', '') \
                .str.replace('万', '').str.replace('--', '0').str.replace(' ', '')
            # 转换为数值型
            df[col] = pd.to_numeric(df[col], errors='coerce').fillna(0)

    return df


def process_date(df):
    """处理上市日期"""
    date_columns = [col for col in df.columns if '日期' in col]

    if not date_columns:
        print("未找到日期列")
        return df

    date_col = date_columns[0]
    print(f"\n处理上市日期列: {date_col}")

    df['上市年份'] = pd.NaT
    df['上市月份'] = pd.NaT
    df['上市日'] = pd.NaT

    processed_count = 0
    for idx, date_str in enumerate(df[date_col]):
        try:
            if pd.notna(date_str) and str(date_str).strip() and str(date_str).strip() != 'nan':
                date_str_clean = str(date_str).strip()

                # 尝试多种日期格式
                for fmt in ['%Y-%m-%d', '%Y/%m/%d', '%Y.%m.%d', '%Y年%m月%d日']:
                    try:
                        date_obj = datetime.strptime(date_str_clean, fmt)
                        df.loc[idx, '上市年份'] = date_obj.year
                        df.loc[idx, '上市月份'] = date_obj.month
                        df.loc[idx, '上市日'] = date_obj.day
                        processed_count += 1
                        break
                    except:
                        continue
        except:
            continue

    print(f"成功处理{processed_count}条日期数据")
    return df


def normalize_data(df):
    """数据归一化"""
    print("\n数据归一化...")

    # 动态识别数值列
    numeric_columns = []
    for col in df.columns:
        if df[col].dtype in [np.int64, np.float64] and col not in ['上市年份', '上市月份', '上市日']:
            numeric_columns.append(col)

    # 也可以根据列名模式识别
    numeric_patterns = ['股息', '分红', '融资', '次数', '总额']
    for col in df.columns:
        if any(pattern in col for pattern in numeric_patterns) and col not in numeric_columns:
            # 确保是数值型
            if pd.to_numeric(df[col], errors='coerce').notna().any():
                numeric_columns.append(col)

    print(f"进行归一化的数值列: {numeric_columns}")

    if numeric_columns:
        # 创建归一化器
        scaler = MinMaxScaler()

        # 归一化处理
        normalized_values = scaler.fit_transform(df[numeric_columns])

        # 创建归一化后的DataFrame
        normalized_df = pd.DataFrame(
            normalized_values,
            columns=[f'{col}_归一化' for col in numeric_columns]
        )

        # 合并数据
        df = pd.concat([df, normalized_df], axis=1)

        print("归一化列:", normalized_df.columns.tolist())

    return df


def main():
    """主函数"""
    try:
        # 1. 加载数据
        df = load_data()

        if df.empty:
            print("数据文件为空")
            return

        # 2. 检查重复值
        check_duplicates(df)

        # 3. 数据清洗
        df_clean = clean_data(df)

        # 4. 处理日期
        df_date = process_date(df_clean)

        # 5. 数据归一化
        df_normalized = normalize_data(df_date)

        # 6. 保存结果
        output_file = "新浪财经历史分红数据_预处理.xlsx"
        df_normalized.to_excel(output_file, index=False, engine='openpyxl')

        print(f"\n预处理完成! 数据已保存到: {output_file}")
        print(f"最终数据形状: {df_normalized.shape}")
        print("\n前5行处理后的数据:")
        print(df_normalized.head())

    except Exception as e:
        print(f"处理过程中出错: {str(e)}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    main()